// tools/Grammar.java
package tools;

import java.util.*;

public class Grammar {
    // 非终结符集合
    public static final Set<String> nonTerminals = new HashSet<>(Arrays.asList(
            "program", "statement_list", "statement",
            "declaration", "loop", "selection", "expression", "condition","assignment","comparison_op","output","cal_op","expression_tail","term","term_tail","factor"
    ));

    // 终结符集合（根据LexicalAnalyzer的Token类型映射）
    public static final Set<String> terminals = new HashSet<>(Arrays.asList(
            "INT", "ID", "ASSIGN", "NUMBER", "WHILE", "IF", "ELSE",
            "LE", "GE", "EQ", "NE", "LT", "GT", "LPAREN", "RPAREN",
            "LBRACE", "RBRACE", "SEMI", "UNKNOWN","PLUS","PRINTF", "INCREMENT", "DECREMENT", "MULTIPLY", "DIVIDE", "MOD","MINUS"
    ));

    // 产生式规则
    public static final List<Production> productions = new ArrayList<>(Arrays.asList(
            new Production("program", Arrays.asList("statement_list")),

            new Production("statement_list", Arrays.asList("statement")),
            new Production("statement_list", Arrays.asList("statement", "statement_list")),

            new Production("statement", Arrays.asList("declaration")),
            new Production("statement", Arrays.asList("loop")),
            new Production("statement", Arrays.asList("selection")),
            new Production("statement", Arrays.asList("assignment")),
            new Production("statement", Arrays.asList("output")),
            //变量声明
            new Production("declaration", Arrays.asList("INT", "ID", "ASSIGN", "expression", "SEMI")),
            new Production("declaration", Arrays.asList("INT", "ID", "SEMI")),
            //变量赋值
            new Production("assignment", Arrays.asList("ID", "ASSIGN", "expression", "SEMI")),
            new Production("assignment", Arrays.asList("ID","INCREMENT", "SEMI")),
            new Production("assignment", Arrays.asList("ID","DECREMENT", "SEMI")),

            //循环语句
            //new Production("loop", Arrays.asList("WHILE", "LPAREN", "condition", "RPAREN", "LBRACE", "statement", "RBRACE")),
            new Production("loop", Arrays.asList("WHILE", "LPAREN", "condition", "RPAREN", "LBRACE", "statement_list", "RBRACE")),


//            new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "LBRACE", "statement", "RBRACE")),
//            new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "LBRACE", "statement", "RBRACE", "ELSE", "LBRACE", "statement", "RBRACE")),
//            //选择语句
//            new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "statement", "ELSE", "statement")),
            //选择语句
            new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "LBRACE", "statement_list", "RBRACE")),
new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "LBRACE", "statement_list", "RBRACE", "ELSE", "LBRACE", "statement_list", "RBRACE")),
// 单独的 if，不带大括号
            //new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "statement")),

// if-else 不带大括号
            //new Production("selection", Arrays.asList("IF", "LPAREN", "condition", "RPAREN", "statement", "ELSE", "statement")),


    //条件语句
            new Production("condition", Arrays.asList("expression", "comparison_op", "expression")),

            new Production("comparison_op", Arrays.asList("LE")),
            new Production("comparison_op", Arrays.asList("GE")),
            new Production("comparison_op", Arrays.asList("EQ")),
            new Production("comparison_op", Arrays.asList("NE")),
            new Production("comparison_op", Arrays.asList("LT")),
            new Production("comparison_op", Arrays.asList("GT")),

            //"PLUS","PRINTF", "INCREMENT", "DECREMENT", "MULTIPLY", "DIVIDE", "MOD"
            //运算符
            new Production("cal_op", Arrays.asList("PLUS")),
            new Production("cal_op", Arrays.asList("MINUS")),
            new Production("cal_op", Arrays.asList("MULTIPLY")),
            new Production("cal_op", Arrays.asList("DIVIDE")),
            new Production("cal_op", Arrays.asList("MOD")),


            //表达式


            new Production("expression", Arrays.asList("term", "expression_tail")),
            new Production("expression_tail", Arrays.asList("PLUS", "term", "expression_tail")),
            new Production("expression_tail", Arrays.asList("MINUS", "term", "expression_tail")),
            new Production("expression_tail", new ArrayList<>()), // ε

            new Production("term", Arrays.asList("factor", "term_tail")),
            new Production("term_tail", Arrays.asList("MULTIPLY", "factor", "term_tail")),
            new Production("term_tail", Arrays.asList("DIVIDE", "factor", "term_tail")),
            new Production("term_tail", Arrays.asList("MOD", "factor", "term_tail")),
            new Production("term_tail", new ArrayList<>()), // ε

            new Production("factor", Arrays.asList("LPAREN", "expression", "RPAREN")),
            new Production("factor", Arrays.asList("ID")),
            new Production("factor", Arrays.asList("NUMBER")),




            new Production("output", Arrays.asList("PRINTF", "LPAREN", "expression", "RPAREN", "SEMI"))
    ));

    // 起始符号
    public static final String startSymbol = "program";

    // 产生式类
    public static class Production {
        public final String lhs;
        public final List<String> rhs;

        public Production(String lhs, List<String> rhs) {
            this.lhs = lhs;
            this.rhs = rhs;
        }

        @Override
        public String toString() {
            return lhs + " → " + String.join(" ", rhs);
        }
    }
}
